package com.vito.oa.act.service.impl;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.vito.act.approval.model.ActApprovalProgressModel;
import com.vito.act.model.ActExTableColsModel;
import com.vito.act.model.ActExTableModel;
import com.vito.act.tool.ActivitiOper;
import com.vito.act.tool.ActivitiTool;
import com.vito.act.tool.OaActivitiTool;
import com.vito.base.authoriza.dao.BaseSqlMapper;
import com.vito.base.authoriza.dao.CreateIdMapper;
import com.vito.base.authoriza.model.BaseSql;
import com.vito.base.authoriza.model.FileModel;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.authoriza.service.FileService;
import com.vito.base.model.DataGrid;
import com.vito.base.model.FtpModel;
import com.vito.base.model.MyHashMap;
import com.vito.base.model.Result;
import com.vito.base.util.Contants;
import com.vito.base.util.FtpHelper;
import com.vito.base.util.StringUtil;
import com.vito.oa.act.constant.OaActContants;
import com.vito.oa.act.dao.OaActProcessMapper;
import com.vito.oa.act.extend.dao.OaActApprovalFormMapper;
import com.vito.oa.act.extend.dao.OaActExBussDefMapper;
import com.vito.oa.act.extend.dao.OaActExTableMapper;
import com.vito.oa.act.extend.model.OaActExBussModel;
import com.vito.oa.act.extend.service.OaActApprovalProgressService;
import com.vito.oa.act.extend.service.OaActProgressTableService;
import com.vito.oa.act.model.ProcessCopyLogModel;
import com.vito.oa.act.service.OaActProcessService;

@Service
public class OaActProcessServiceImpl implements OaActProcessService {
	private static final Logger log = LoggerFactory.getLogger(OaActProcessService.class);
	@Autowired 
	private OaActProcessMapper oaActProcessMapper;
	@Autowired
	private OaActApprovalFormMapper actApprovalFormMapper;
	@Autowired
	private OaActApprovalProgressService actApprovalProgressService;
	@Autowired
	private BaseSqlMapper baseSqlMapper; 
	@Autowired
	private CreateIdMapper createIdMapper;
	@Autowired
	private OaActExBussDefMapper actExBussDefMapper;
	@Autowired
	private OaActExTableMapper actExTableMapper;
	@Autowired
	private FileService fileServiceImpl;
	@Autowired
	private OaActProgressTableService oaActProcessServiceImpl;
	
	@Override
	public String importProcess(String filePath) {
		String Path= filePath.substring(filePath.lastIndexOf("/")+1);
		Path = Path.substring(0,Path.lastIndexOf("_")+1).replace("_", "/");
		Path = Path.substring(1,Path.length());
		String fileIdName = filePath.substring(filePath.lastIndexOf("/")+1);
		fileIdName = fileIdName.substring(fileIdName.lastIndexOf("_")+1);
		String fileId = fileIdName.substring(fileIdName.lastIndexOf("_")+1,fileIdName.lastIndexOf("."));
		String fileName = fileIdName;
		FtpModel ftpModel = new FtpModel();
		ftpModel.setFilePath(Path);
		ftpModel.setFileNewName(fileIdName);
		FileModel fileModel = new FileModel();
		fileModel.setFileId(fileId);
		List<FileModel> file = fileServiceImpl.queryFile(fileModel);
		if(null!=file && !file.isEmpty()){
			fileModel = file.get(0);
			fileName = fileModel.getFileName()+"."+fileModel.getFileExt();
		}	
		
		InputStream inputStream = new FtpHelper().readFileStream(ftpModel);
		
		Deployment deployment = ActivitiTool.getRepositoryService().createDeployment().addInputStream(fileName, inputStream)
				.deploy();
		List<String> reousrceNames = ActivitiTool.getRepositoryService().getDeploymentResourceNames(deployment.getId());
		System.out.println(reousrceNames.get(0));
		ProcessDefinition processDefinition = ActivitiTool.getRepositoryService().createProcessDefinitionQuery()
				.deploymentId(deployment.getId()).singleResult();
		System.out.println("Found process definition [" + processDefinition.getName() + "] with id ["
				+ processDefinition.getId() + "]");
		
		return deployment.getId();
	}

	@Override
	public DataGrid<MyHashMap<String,String>> querySysProgressByPage(OaActExBussModel process) {
		DataGrid<MyHashMap<String,String>> data = new DataGrid<MyHashMap<String,String>>();
			data.setRows(oaActProcessMapper.querySysProgressByPage(process));
			data.setTotal(process.getTotal());
		return data;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> queryProcessMainTableInfo(String businessId, String processKey){
		MyHashMap<String ,Object> resultMap = new MyHashMap<String,Object>();
		MyHashMap<String, Object> data = oaActProcessServiceImpl.queryBussInfo(processKey, Contants.FORM_PROCESS_START, businessId, Contants.FORM_PROCESS_MAIN_TASKID);
		MyHashMap<String, Object> main = ((List<MyHashMap<String, Object>>) data.get(Contants.FORM_KEY_MAIN)).get(0);
		Object colsValue =  main.get(Contants.FORM_KEY_DATA);
		Object cols = main.get(Contants.FORM_KEY_COLS);
		resultMap.put(Contants.FORM_KEY_DATA, colsValue);
		resultMap.put(Contants.FORM_KEY_COLS, cols);
		return resultMap;
	}
	
	@Override
	public Result importSysProcessToDefined(ActApprovalProgressModel process,UserModel user){
		Result rs = new Result();
		try{
			
			List<String> nodesList = oaActProcessMapper.queryNodesByProcessKey(process.getProcessKey());
			for(int i = nodesList.size()+1;i<=OaActContants.ACTIVITI_PROCESS_DEFAULT_NODE_NUM;i++){
				nodesList.add("第"+i+"审核人");
			}
			String nodeNames = StringUtils.join(nodesList.toArray(new String[nodesList.size()]), ",");
			process.setProcessNodeNames(nodeNames);
			process.setMsgType("rlytx");
			process.setCreatedept(user.getDeptParentId());
			process.setCreateuser(user.getUserId());
			process.setProcessName(process.getBusinessName());
			
			String formId=importSysFormToDefined(process,user);	
			String oldBusinessId = process.getBusinessId();
			if(formId != null){
				rs= actApprovalProgressService.addProgress(process, formId);
			}
			if (rs.getCode()==0){
				ProcessCopyLogModel copyModel = new ProcessCopyLogModel();
				copyModel.setBusinessId(oldBusinessId);
				copyModel.setNewBusinessId(process.getBusinessId());
				copyModel.setOperUser(user.getUserId());
				copyModel.setOperDept(user.getDeptParentId());
				copyModel.setNewFormId(formId);
				oaActProcessMapper.saveProcessImportLog(copyModel);
				rs.setMsg("导入成功，请转到流程管理内查看");
			}
		}catch(Exception e){
			log.error("流程拷贝失败",e);
			rs.setCode(Result.CODE_ERROR);
			rs.setMsg("执行异常");
			return rs;
		}
		return rs;
	}
	
	@Override
	public boolean hasImportLog(String businessId, String deptId) {	
		return oaActProcessMapper.queryCopyLog(businessId, deptId)>0;
	}
	
	private String importSysFormToDefined(ActApprovalProgressModel process,UserModel user) throws Exception{
		String formId = null;
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(Contants.FORM_KEY_KEY, process.getProcessKey());
		map.put(Contants.FORM_KEY_NODEID, Contants.FORM_PROCESS_START);
		// 查询当前业务的当前节点下所有的表
		List<ActExTableModel> baseInfos = actExTableMapper.queryActExTableByKeyAndNode(map);
		
		for(ActExTableModel baseInfo : baseInfos){
			if(null == formId){
				formId = StringUtil.getUUID();
			}
			String detail_key = StringUtil.getUUID();
			String tableKey = baseInfo.getTableKey();
			Map<String, String> formMap = new HashMap<String, String>();
			Map<String, String> bussDefRef = new HashMap<String, String>();
			//拷贝主表
			if(baseInfo.getParentTableKey()!=null){
				//1.保存基本表信息
				formMap.put("TABLE_KEY", OaActContants.COMM_TABLE_KEY_SUB);
				bussDefRef.put("tableKey", OaActContants.COMM_TABLE_KEY_SUB);
			}else{
				bussDefRef.put("tableKey", Contants.COMM_TABLE_KEY);
			}
			
			formMap.put("form_id", formId);
			formMap.put("form_name",baseInfo.getShortNameCh());
			formMap.put("form_des", baseInfo.getShortNameCh());
			formMap.put("user_id", user.getUserId());
			formMap.put("dept_id", user.getDeptParentId());
			
			actApprovalFormMapper.saveForm(formMap);
			//2.保存表单字段
			List<ActExTableColsModel> colsModels = oaActProcessMapper.querySysProcessTableCols(tableKey);		
			saveTableCols(colsModels,detail_key,bussDefRef.get("tableKey"));			
			
			//3.保存流程节点扩展信息
			
			bussDefRef.put("refKey", formId);
			bussDefRef.put("detailKey", detail_key);
			bussDefRef.put("operType", Contants.COMM_OPER_TYPE);
			bussDefRef.put("isMore", baseInfo.getIsMore());
			actExBussDefMapper.saveActExBussDefRef(bussDefRef);
		}
		return formId;
	}
	
	private void saveTableCols(List<ActExTableColsModel> colsModels,String detail_key,String tableKey ) throws Exception{
		int isSuccess=1;
		for(int i = 0; i < colsModels.size(); i++){
			ActExTableColsModel col = colsModels.get(i);
			col.setTableKey(tableKey);
			col.setColName("col"+i);
			col.setFunName(null);
			col.setOrderNum(i);
			if(col.getOperators() == null){
				col.setOperators("=");
			}
			//若为下拉、多选等菜单，备份菜单数据从tbl_base_code到act_ex_user_code
			if(Contants.FORM_SHOWTYPE_SELECT.equals(col.getShowType())
					||Contants.FORM_SHOWTYPE_MSELECT.equals(col.getShowType())){
				String dataId = col.getDataId();
				String[] param = col.getDataOnchange().split(",");
				BaseSql sql = new BaseSql();
				sql.setState(Contants.BASE_STATE);
				sql.setQueryId(dataId);
				sql = baseSqlMapper.queryBaseSqlById(sql);
				List<Map<String,String>> maps =oaActProcessMapper.queryDataBySql(sql.getMapParam(param));
				String batchId = "UC"+createIdMapper.getId("ACT_EX_UC");
				for(int j = 0;j<maps.size();j++){				
						Map<String, String> userCode = new HashMap<String,String>();
						userCode.put("batchid", batchId);
						userCode.put("code_name",maps.get(j).get("TEXT"));
						userCode.put("order_num", j+"");
						isSuccess = (isSuccess & actApprovalFormMapper.saveUserCode(userCode));			
				}
				col.setDataId(batchId);
			}
			actApprovalFormMapper.saveActExTableCols(col);
			//保存表单元素对应关系
			Map<String, String> bussDefRefCol = new HashMap<String, String>();
			bussDefRefCol.put("detailKey", detail_key);
			bussDefRefCol.put("colKey", col.getColKey());
			actExBussDefMapper.saveActExBussDefRefCol(bussDefRefCol);
		}
	}

	@Override
	public void importBpmn(String dir) {
		OaActivitiTool.importBpmn(dir);
	}

	@Override
	public void exportBpmn(String dir) {
		OaActivitiTool.exportBpmn(dir);
	}

	@Override
	public void uninstallBpmn(String key,String DeployId) {
		if(key != null){
			List<Deployment> list = ActivitiTool.getRepositoryServiceImpl().createDeploymentQuery()
					.processDefinitionKey(key).list();
			if(list != null && list.size() >0){
				for(Deployment dep : list){
						ActivitiOper.undeployByDeploymentId(dep.getId());
				}
			}
		}
		if(DeployId != null){
			ActivitiOper.undeployByDeploymentId(DeployId);
		}

	}
}